package com.basker.pisces.orm.statement;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.basker.pisces.orm.data.meta.TableMeta;

public class DataTableWriteCommandWrapper {
    private static final Comparator<Object> PKVALUE_COMPARATOR = new PkValueComparator();
    private static final Comparator<WriteCommand> WRITECOMMAND_COMPARATOR = new WritecommandComparator();

    private TableMeta tableMeta;

    private List<Object> deletePkValues;
    private List<UpdateCommand> updateCommands;
    private List<InsertCommand> insertCommands;

    public DataTableWriteCommandWrapper(TableMeta tableMeta) {
        this.tableMeta = tableMeta;
    }

    public void addDeletePkValues(Collection<Object> deletePkValues) {
        if (this.deletePkValues == null) {
            this.deletePkValues = new ArrayList<>();
        }

        this.deletePkValues.addAll(deletePkValues);
    }

    public void addInsertCommand(InsertCommand insertCommand) {
        if (this.insertCommands == null) {
            this.insertCommands = new ArrayList<>();
        }
        insertCommands.add(insertCommand);
    }

    public void addUpdateCommand(UpdateCommand updateCommand) {
        if (this.updateCommands == null) {
            this.updateCommands = new ArrayList<>();
        }
        updateCommands.add(updateCommand);
    }

    public List<Object> getDeletePkValues() {
        return deletePkValues != null ? deletePkValues : Collections.emptyList();
    }

    public List<InsertCommand> getInsertCommands() {
        return insertCommands != null ? insertCommands : Collections.emptyList();
    }

    public TableMeta getTableMeta() {
        return tableMeta;
    }

    public List<UpdateCommand> getUpdateCommands() {
        return updateCommands != null ? updateCommands : Collections.emptyList();
    }

    /**
     * 对语句按主键值排序，减少死锁发生的概率
     */
    public void sortByPkValues() {
        if (this.insertCommands != null && this.insertCommands.size() > 1) {
            Collections.sort(this.insertCommands, WRITECOMMAND_COMPARATOR);
        }

        if (this.updateCommands != null && this.updateCommands.size() > 1) {
            Collections.sort(this.updateCommands, WRITECOMMAND_COMPARATOR);
        }

        if (this.deletePkValues != null && this.deletePkValues.size() > 1) {
            Collections.sort(this.deletePkValues, PKVALUE_COMPARATOR);
        }
    }

    private static class PkValueComparator implements Comparator<Object> {

        @Override
        public int compare(Object v1, Object v2) {
            if (v1 == null || v2 == null) {
                return 0;
            }

            if (v1 instanceof Number && v2 instanceof Number) {
                long l1 = ((Number) v1).longValue();
                long l2 = ((Number) v2).longValue();

                return Long.compare(l1, l2);
            }

            return String.valueOf(v1).compareTo(String.valueOf(v2));
        }

    }

    private static class WritecommandComparator implements Comparator<WriteCommand> {

        @Override
        public int compare(WriteCommand o1, WriteCommand o2) {
            Object v1 = o1.getPkFieldObject().getValue();
            Object v2 = o2.getPkFieldObject().getValue();

            if (v1 == null || v2 == null) {
                return 0;
            }

            return PKVALUE_COMPARATOR.compare(v1, v2);
        }

    }

}
